package cn.com.zzl.util;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;
import java.sql.Connection;

/**
 * Description：DB工具类，即database工具类
 * Created by 朱正磊 on 2017-06-14 9:39.
 */
public class DBUtil {
	//数据源，这里我们使用的是c3p0。
	private static DataSource ds ;
	//ThreadLocal实例通常是类中的私有静态字段，一般用于存储与线程关联的局部变量。
	private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>();
	//类一加载就初始化数据源
	static{
		ds = new ComboPooledDataSource();
	}
	//默认构造方法私有化，防止被实例化
	private DBUtil(){

	}
	//获取数据源实例
	public static DataSource getDataSource(){
		return ds;
	}

	/**
	 * @Desc 从数据库连接池获取connection连接
	 * @return
	 */
	public static Connection getConnection(){
		try {
			//获取当前线程绑定的连接
			Connection connection = threadLocal.get();
			if(connection == null){//如果当前线程没有绑定连接
				connection = ds.getConnection();
				threadLocal.set(connection);
			}
			return connection;
		} catch (Exception e) {
			//抛出运行时异常，结束程序运行。
			throw new RuntimeException(e);
		}
	}

	/**
	 * @Desc 开启事务
	 */
	public static void beginTransaction(){
		try {
			//获取当前线程绑定的连接，然后开启事务，当然了这里也可以直接调用threadLocal.get()获取绑定的连接
			Connection connection = getConnection();
			//设置自动提交为false，即手动提交事务保证整个操作的完整性，默认自动提交事务不安全！
			connection.setAutoCommit(false);
		} catch (Exception e) {
			//抛出运行时异常，结束程序运行。
			throw new RuntimeException(e);
		}
	}

	/**
	 * @Desc 提交事务
	 */
	public static void commitTransaction(){
		try {
			//获取当前线程绑定的连接
			Connection connection = threadLocal.get();
			if(connection != null){//如果连接存在
				connection.commit();
			}
		} catch (Exception e) {
			//抛出运行时异常，结束程序运行。
			throw new RuntimeException(e);
		}
	}

	/**
	 * @Desc 关闭连接
	 */
	public static void closeConnection(){
		try {
			//获取当前线程绑定的连接
			Connection connection = threadLocal.get();
			if(connection != null){//如果连接存在
				connection.close();
			}
		} catch (Exception e) {
			//抛出运行时异常，结束程序运行。
			throw new RuntimeException(e);
		} finally {
			//移除threadLocal
			threadLocal.remove();
		}
	}

	/**
	 * @Desc 事务回滚
	 */
	public static void rollback(){
		try {
			//获取当前线程绑定的连接
			Connection connection = threadLocal.get();
			if(connection != null){//如果连接存在
				//回滚事务
				connection.rollback();
			}
		} catch (Exception e) {
			//抛出运行时异常，结束程序运行。
			throw new RuntimeException(e);
		}
	}

}
